
#ifndef DTAPONTO_H
#define DTAPONTO_H

#include "DTAStructBase.h"
#include <iostream>
#include <cmath>

using namespace std;



class DTAPonto: public DTAStructBase
{
public:
    //metodos:
    DTAPonto(); //construtor
    ~DTAPonto(); //destrutor
    void print(); //imprime as coordenadas

    inline int toHash(int sizeHash); //método necessário para mapear os pontos na tabela hash

    //operados sobre os pontos.
    bool operator <= (DTAPonto pt); //===
    bool operator > (DTAPonto pt);  //=====> Este conjunto de operadores utiliza uma funcao de avaliacao, para saber se um ponto é menor que outro
    bool operator < (DTAPonto pt);  //=====> dado que teríamo que comparar nas 3 dimensoes 2*x^2 + 3*y^3 + 5*z^5 (x,y,z -> coordenadas)
    bool operator >= (DTAPonto pt); //===

    bool operator != (DTAPonto pt);// utiliza das proprias coordenadas dos pontos
    bool operator ==(DTAPonto pt);// utiliza das proprias coordenadas dos pontos

    //atributos: eles nao são do tipo private, devido ao fato de nao precisarmos de métodos para acessar esses membros, visto que
    //seriam extremamente simples e mais sobrecarregariam a classe do que ajudariam
    double x,y,z; //cordenadas dos pontos
        
private:

    inline  double avalFunc()   //funcao de avaliacao de um ponto -> semelhante ao hash
    {
        return 3.0*x*x*x+ 5.0*y*y*y*y*y + 7.0*z*z*z*z*z*z*z;
    }


};

DTAPonto::DTAPonto()
{
    x= 0.0;
    y= 0.0;
    z= 0.0;
    active = true;    
}


DTAPonto::~DTAPonto()
{
}


void DTAPonto::print()
{
    cout << "id: " << id << " active: " << active << " x: " << x << " y: " << y << " z: " << z << endl;
}

inline int DTAPonto::toHash(int sizeHash)
{
    int mod;
    double ptX;
    double ptY;
    double ptZ;

    ptX = x;
    ptY = y;
    ptZ = z;

    ptX *= 1000;
    ptY *= 1000;
    ptZ *= 1000;

    
    mod = fmod(3.0*ptX*ptX*ptX + 5.0*ptY*ptY*ptY*ptY*ptY + 7.0*ptZ*ptZ*ptZ*ptZ*ptZ*ptZ*ptZ,sizeHash);

    if (mod <0) mod = (-1)*mod;
    return mod;
}

bool DTAPonto::operator <=(DTAPonto pt)
{
    if(trunc(avalFunc()*100000) <= trunc(pt.avalFunc()*100000) )
        return true;
    else
        return false;
}


bool DTAPonto::operator <(DTAPonto pt)
{
     if(trunc(avalFunc()*100000) < trunc(pt.avalFunc()*100000) )
        return true;
    else
        return false;
}

bool DTAPonto::operator >(DTAPonto pt)
{
     if(trunc(avalFunc()*100000) > trunc(pt.avalFunc()*100000) )
        return true;
    else
        return false;
}

bool DTAPonto::operator >=(DTAPonto pt)
{
     if( trunc(avalFunc()*100000) >= trunc(pt.avalFunc()*100000) )
        return true;
    else
        return false;
}


bool DTAPonto::operator ==(DTAPonto pt)
{
    if( trunc(x*10000) == trunc(pt.x*10000)  &&  trunc(y*10000) == trunc(pt.y*10000) && trunc(z*10000) == trunc(pt.z*10000)) //trunc( ( 2*pow(x,2) + 3*pow(y,3) + 5*pow(z,5))*100000) == trunc((2*pow(pt.x,2) + 3*pow(pt.y,3) + 5*pow(pt.z,5))*100000))//
        return true;
    else
        return false;
}

bool DTAPonto::operator !=(DTAPonto pt)
{
    if( trunc(x*10000) != trunc(pt.x*10000)  ||  trunc(y*10000) != trunc(pt.y*10000) || trunc(z*10000) != trunc(pt.z*10000))
        return true;
    else
        return false;
}

#endif // DTAPONTO_H


